/*!
\copyright  Copyright (c) 2020 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file       watchdog.h
\brief      Software Watchdog Timers

The service provides a set of software watchdogs timers.  These timers can be used by various components
to guard against lockups and timeouts.

Each component that requires a watchdog should create a new watchdog using the CREATE_WATCHDOG() macro, for example:

CREATE_WATCHDOG(test_wd):

All the watchdogs are stored in a seperate area of memory which is then checksummed to provide protection against
this area of memory getting corrupted or overwritten.

To start a watchdog timer the Watchdog_Kick(watchdog_state_t *state, uint8 time_s) function is used where time_s is the time in seconds for when
the watchdog timer will expire.  When the timer expires the chip will panic and reboot.  For example using the watchdog created above to start
a 5 second timer:

Watchdog_Kick(&test_wd, 5)

A watchdog timer can be stopped by calling Watchdog_Stop(watchdog_state_t *state), for example:

Watchdog_Stop(&test_wd)

A watchdog timer can be re-started when it's either stoppped or still running, if it's running the timer will be extended from the
current time.

Each watchdog only takes 1 byte of RAM.  To keep RAM usage low the accuracy of the watchdog timer is around 1 second and
is guaranteed to by at least as long as requested.  For example a 5 second watchdog timer may actually be 6 seconds.

*/

#ifndef WATCHDOG_SERVICE_H_
#define WATCHDOG_SERVICE_H_

/*! Storage type for a watchdog */
typedef uint8 watchdog_state_t;

#ifdef INCLUDE_WATCHDOG

/*! \brief Macro to create a software watchdog
*/
#define CREATE_WATCHDOG(NAME) \
_Pragma("datasection watchdog_states") \
watchdog_state_t NAME

/*! Symbols generated by linker for beginning and end of watchdog RAM section */
extern watchdog_state_t watchdog_states_begin[];
extern watchdog_state_t watchdog_states_end[];

/*! \brief Initialise the software watchdog component
 *
    This function must be called before any other APIs in this component.
*/
void Watchdog_Init(void);

/*! \brief (Re)start a software watchdog timer

    This function must be called before any other APIs in this component.

    \param[in] state Pointer to watchdog state.
    \param[in] time_s New expiry time in seconds.
*/

void Watchdog_Kick(watchdog_state_t *state, uint8 time_s);


/*! \brief Stop a software watchdog timer

    This function must be called before any other APIs in this component.

    \param[in] state Pointer to watchdog state.
*/
void Watchdog_Stop(watchdog_state_t *state);

#else

/*! NULL macros when watchdog support has been excluded from build */
#define CREATE_WATCHDOG(NAME)           watchdog_state_t NAME
#define Watchdog_Init(period)           UNUSED(period)
#define Watchdog_Kick(state, time_ms)   do {UNUSED(time_ms);UNUSED(state);} while(0)
#define Watchdog_Stop(state)            do {UNUSED(state);} while(0)

#endif

#endif /* WATCHDOG_SERVICE_H_ */
